#include "Photo.h"
#include <fstream>
#include "common/HashUtility.h"

namespace etu {
namespace genealogy_tree {

using etu::common::HashUtility;

Photo::Photo(const std::string& filePath) throw(FileNotFoundException) {
    std::ifstream file;

    file.open(filePath.c_str(), std::ios::binary);
    
    if(!file.is_open()) {
        throw FileNotFoundException("Файл, содержащий фотографию, не существует");
    }

    file.seekg(0, std::ios::end);
    this->dataBufferLength = file.tellg();
    file.seekg(0, std::ios::beg);

    this->dataBuffer = new unsigned char[this->dataBufferLength];
    file.read((char *) this->dataBuffer, this->dataBufferLength);
    file.close();

    this->hash = HashUtility::hashFile(filePath);
}

Photo::Photo(const std::string& hash, unsigned char* dataBuffer, int dataBufferLength) {
    if(dataBufferLength > 0) {
        if(dataBuffer != NULL) {
            this->dataBuffer = Photo::copyBuffer(dataBuffer, dataBufferLength);
            this->dataBufferLength = dataBufferLength;
            this->hash = hash.empty()
                    ? HashUtility::hashBuffer(dataBuffer, dataBufferLength) : hash;
        } else {
           this->dataBuffer = NULL;
           this->dataBufferLength = 0;
           this->hash = "";
        }
    } else {
        this->dataBuffer = NULL;
        this->dataBufferLength = 0;
        this->hash = "";
    }
}

Photo::Photo(unsigned char* dataBuffer, int dataBufferLength) {
    Photo("", dataBuffer, dataBufferLength);
}

Photo::Photo(const Photo& orig) {
    this->dataBuffer = Photo::copyBuffer(orig.dataBuffer, orig.dataBufferLength);
    this->dataBufferLength = orig.dataBufferLength;
    this->hash = orig.hash;
}

Photo::~Photo() {
    delete[] this->dataBuffer;
}

std::string Photo::getHash() const {
    return this->hash;
}

unsigned char* Photo::getData() const {
    return this->dataBuffer;
}

int Photo::getDataLength() const {
    return this->dataBufferLength;
}

Photo* Photo::empty() {
    return new Photo(NULL, 0);
}

bool Photo::isEmpty(const Photo& photo) {
    return (photo.dataBuffer == NULL) || (photo.dataBufferLength == 0);
}

unsigned char* Photo::copyBuffer(unsigned char* buffer, int length) {
    unsigned char* ret = new unsigned char[length];

    for(int i = 0; i < length; i++) {
        ret[i] = buffer[i];
    }

    return ret;
}

}
}
